# -*- encoding: utf-8 -*-

# Copyright 2010 István Szentandrási
# <etude-music-player@googlegroups.com>

# This file is part of Etude.
#
# Etude is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as 
# published by the Free Software Foundation, either version 3 
# of the License, or (at your option) any later version.
#
# Etude is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Etude. If not, see <http://www.gnu.org/licenses/>.

import gtk
import pango
import gobject
from .. import client
ec = client

from .. import config as ecfg
import re, xmmsclient
import minfo
import urllib, os

class CollectionView(gtk.TreeView):

    """
    A TreeView showing the contents of a collection.
    Usable in plugins
    """

    def __init__(self, plugin, format, coll_name = '', namespace = "Collections", 
            default_order = None, sortable=False):
        """
        format is a string containing the format of the columns and each entr
        default order should be a list
        """
        gtk.TreeView.__init__(self)
        self.plugin = plugin
        self.client = plugin.control.client
        
        self.coll_name = coll_name
        self.namespace = namespace
        self.collection = None
        self.ids = [] #list of ids needed for simpler searching
        
        # list of handler ids needed when collection is a collection
        self._collection_hids = []
        # list of handler ids needed when the collection is a playlist
        self._playlist_hids = [] 

        self.start_menu = None
        self.end_menu = None
        self.set_menu(None)
        
        self.enable_sort = sortable
        self.playlist_position = -1 #if the collection is a playlist, the position
        self.default_order = default_order
        
        self.set_format(format) #structure of the model
        self.show_row_numbers = False
        
        self.show()
        self.plugin.bind(self.client, 'e_medialib_entry_changed', self.entry_changed)
        self.last_x = 0
        self.last_y = 0
        self.connect('button-press-event', self.on_get_positions)
        self.connect('drag_data_received', self.on_drag_data_recieved)
        self.connect('drag-data-get', self.on_drag_data_get)
        self.connect('drag-begin', self.on_drag_begin)
        self.connect_after('drag-begin', self.on_after_drag_begin)
        self.connect_after('query-tooltip', self.on_tooltip)
        self.last_tooltip_path = (-1,)
        self.set_has_tooltip(True)

    def on_tooltip(self, widget, x, y, keyboard_mode, tooltip):
        path = widget.get_path_at_pos(
                *widget.convert_widget_to_bin_window_coords(x, y))
        if path == None:
            return False
        if path[0] != self.last_tooltip_path:
            self.last_tooltip_path = path[0]
            return False
        ind = widget.get_columns().index(path[1])
        model = self.get_model()
        tooltip.set_markup(model[path[0]][ind+2])
        return True

    def set_sortable(self, enable=True):
        self.enable_sort=enable
        self.set_format(self.format)

    def set_menu(self, start_menu = None, end_menu=None):
        if not start_menu:
            menu = gtk.Menu()
        else:
            menu = start_menu
            menu.append(gtk.SeparatorMenuItem())
        
        item = gtk.MenuItem(label= _("Edit tags..."))
        item.connect('activate', self.edit_song_tags)
        menu.append(item)
        if end_menu:
            menu.append(gtk.SeparatorMenuItem())
            for item in end_menu.get_children():
                end_menu.remove(item)
                menu.append(item)
        self.menu = menu

    def on_get_positions(self, widget, event, data = None):
        """used while d'n'd. When selecting a few, and clicking on
        the selected while holding ctrl will unselect the song under 
        the cursor, so we reselect it

        also used to popup menu
        """
        self.last_x = event.x
        self.last_y = event.y
        if event.button == 3:
            sel = self.get_selection()
            if sel.count_selected_rows() < 2:
                path = self.get_path_at_pos(int(self.last_x), int(self.last_y))
                if path != None:
                    sel.unselect_all()
                    sel.select_path(path[0])

            self.menu.show_all()
            self.menu.popup(None, None, None, event.button, event.time)
            return True

    def edit_song_tags(self, widget, data = None):
        ids = self.get_selected_ids()
        minfo.edit_songs(self.get_toplevel(), self.plugin.control, ids)
        return False

    def get_ids(self):
        """
        get the list of ids
        If the collection is an idlist, the id's will be in correct order
        """
        model = self.get_model()
        if model is self.sort_model:
            return [row[0] for row in model]
        else:
            return self.ids

    def get_coll_name(self):
        """
        get the collection name
        """
        return self.coll_name    

    def get_collection(self):
        """
        get the showed collection
        """
        if self.__check_medialist(self.collection):
            l = len(self.collection.ids)
            [self.collection.ids.remove(0) for i in xrange(l)]
            [self.collection.ids.append(id) for id in self.ids]
        return self.collection

    def get_collection_type(self):
        return self.collection.__class__
    
    def set_show_row_numbers(self, show):
        """useful for playlists"""
        self.show_row_numbers = show


    def get_selected_ids(self):
        """get the list of selected ids"""
        ret_list = []
        viewselection = self.get_selection()
        model, path_list = viewselection.get_selected_rows()
        for path in path_list:
            iter = model.get_iter(path) 
            ret_list.append(model.get_value(iter, 0))
        return ret_list

    def get_selected_positions(self):
        """get the list of selected positions - useful for playlists where for manipulation
        you need positions"""
        ret_list = []
        viewselection = self.get_selection()
        model, path_list = viewselection.get_selected_rows()
        [ret_list.append(pos[0]) for pos in path_list]
        return list(ret_list)

    def set_format(self, format):
        """
        set the format, which defines how the treeview should look like
        for details on the format of the pattern see config.py
        """
        self.format = format
        self.column_types = [gobject.TYPE_INT, gobject.TYPE_INT] + ecfg.parse_column_types(format)
        self.list_struct = [ec.XMEP_ID, ec.XMEP_STATUS] + ecfg.parse_column_xmms(format)
        header_list = ecfg.parse_column_headers(format)
        self.simple_list = bool(re.match(r'\s*(\s*<.*?>\s*\|)*\s*<.*?>\s*$', format))
        self.list_model = gtk.ListStore(*self.column_types)
        self.sort_model = gtk.TreeModelSort(self.list_model)
        #self.sort_model.set_sort_column_id(2, gtk.SORT_ASCENDING)
        self.set_model(self.list_model)
        #clear columns
        for column in self.get_columns():
            self.remove_column(column)

        #create columns
        for ind in xrange(len(header_list)):
            renderer = gtk.CellRendererText()
            renderer.set_data("column", ind)
            #maybe change this
            if _('url') == self.list_struct[ind+2]:
                renderer.set_property('ellipsize', pango.ELLIPSIZE_START)
            else:
                renderer.set_property('ellipsize', pango.ELLIPSIZE_END)

            col = gtk.TreeViewColumn( header_list[ind], renderer, markup= ind+2) #first two given

            col.set_resizable(True)
            shorter = (_(ec.XMEP_ID),_(ec.XMEP_YEAR),
                    _(ec.XMEP_TRACKNR), _(ec.XMEP_BITRATE),
                    _(ec.XMEP_DURATION), _(ec.XMEP_CHANNELS),
                    _(ec.XMEP_SAMPLERATE))
            
            if self.list_struct[ind+2] in shorter:
                col.set_min_width(50)
            else:
                col.set_min_width(100)
            col.set_expand(True)
            col.set_sort_column_id(ind+2)
            col.set_cell_data_func(renderer, self.current_highlight)
            self.append_column(col)

        #fill the model
        if self.coll_name!= '':
            self.set_coll_name(self.coll_name, self.namespace)
        else:
            del self.ids[0:]
            self.list_model.clear()

    def current_highlight(self, column, cell, model, iter):
        """
        when the collection is from Playlists namespace the current
        position is highlighted
        The unavailable medialib entrys are stroke through.
        The entrys that are currently resolving are shown italic
        If the show_row_numbers is set, the row numbers are shown
        """
        cell.set_property("weight", pango.WEIGHT_NORMAL)
        if self.namespace == "Playlists":
            index = model.get_path(iter)[0]
            if self.playlist_position == index:
                cell.set_property("weight", pango.WEIGHT_BOLD)
        if cell.get_data('column') == 0:
            if self.show_row_numbers:
                attr = cell.get_property('attributes')
                text = unicode(cell.get_property('text'))
                path = model.get_path(iter)
                app_str = str(path[0]+1)+". "
                cell.set_property('text', app_str + text)
                new_attr = pango.AttrList()
                new_attr.splice(attr, len(app_str), len(text))
                cell.set_property('attributes', new_attr)
        status = model.get_value(iter, 1)
        cell.set_property('strikethrough', status == client.MEDIALIB_ENTRY_STATUS_NOT_AVAILABLE)
        if status == client.MEDIALIB_ENTRY_STATUS_RESOLVING:
            cell.set_property('style', pango.STYLE_ITALIC)
        else:
            cell.set_property('style', pango.STYLE_NORMAL)


    def _register_cbs(self, collections = False, playlists = False):
        """
        register callbacks for the collection, so we get updates on the entrys
        in the collection
        The handler ids are stored
        """
        if collections and len(self._collection_hids) == 0:
            self._collection_hids.append(
                    self.plugin.bind(self.client, 'e_collection_changed', self.collection_changed_cb) 
                    )
        elif collections == False:
            for hid in self._collection_hids:
                self.plugin.unbind(self.client, hid)
            self._collection_hids = []
        #playlists
        if playlists and len(self._playlist_hids) == 0:
            self._playlist_hids.extend( [
                self.plugin.bind(self.client, 'e_collection_changed', 
                    self.collection_changed_cb),
                self.plugin.bind(self.client, 'e_playlist_changed', 
                    self.playlist_changed_cb),
                self.plugin.bind(self.client, 'e_playlist_current_pos', 
                    self.playlist_current_pos_cb) 
                ])
        elif playlists == False:
            for hid in self._playlist_hids:
                self.plugin.unbind(self.client, hid)
            self._playlist_hids = []

    def set_default_order(self, order):
        """set the default order the entries are shown"""
        self.default_order = order

    def set_default_order_format(self, order):
        """set the default order according to the pattern given"""
        self.default_order = ecfg.parse_column_xmms(order)

    def get_default_order(self):
        """get the default order of the entries in the treeview"""
        return self.default_order

    def get_order(self):
        model = self.get_model()
        if model is self.sort_model:
            order = []
            sort_id,asc = model.get_sort_column_id()
            if sort_id >= 0:
                splitted = self.format.split('|')
                order = ecfg.parse_column_xmms(splitted[sort_id-2])
                if asc == gtk.SORT_DESCENDING:
                    order = ['-'+field for field in order]
            return ecfg.list_unique(order+self.default_order)
        else:
            return self.default_order
    """ The order function are usable only with collection, that aren't
        idlists, as idlists have defined order
    """


    def set_coll(self, coll, order = None):
        """
        set the collection - order should be a list of properties
        """
        self.coll_name = ''
        self.namespace = "Collections"
        if order != None:
            self.default_order = order
        self._get_coll(coll)
        self._register_cbs(False, False)

    def set_coll_name(self, coll_name, namespace = "Collections", order = None):
        """
        set the collection - order should be a list of properties
        """
        self.coll_name = coll_name
        self.namespace = namespace
        if order != None:
            self.default_order = order
        cl = ec.Collection(self.client)
        cl.get(coll_name, namespace, cb = self._get_coll)
        if namespace == "Collections":
            self._register_cbs(True, False)
        else:
            self._register_cbs(False, True)

    def _get_coll(self, coll):
        cl = ec.Collection(self.client)

        if self.__check_medialist(coll):
            default_order = None
            try:
                self.playlist_position = int(coll.attributes['position'])
            except:
                self.playlist_position = -1
        elif (self.default_order != None)  and self.namespace == "Collections":
            default_order = self.default_order
        else:
            self.playlist_position = -1
            default_order = self.list_struct[1:]
        self.collection = coll
        cl.query_infos(fields = self.list_struct, coll = coll, order = default_order,
                cb = self.__fill_model)

    def __fill_model(self, result):
        self.list_model.clear()
        self.set_model(None)
        #don't show the model until filling it up
        
        ids = []
        coll = self.collection
        is_idlist=False
        if self.__check_medialist(coll): 
            #TODO after collections 2.0 this won't be necessary
            #but currently duplicates and order is messed up
            sinfos = {}
            for row_dict in result:
                sinfos[row_dict['id']] = row_dict
            ids = coll.ids.list()
            if self.simple_list:
                for id in ids:
                    d_info = sinfos[id]
                    row = [ecfg.format_value(val, d_info[val]) for val in self.list_struct]
                    self.list_model.append(row)
            else:
                for id in ids:
                    d_info = sinfos[id]
                    self.list_model.append( [id,d_info[ec.XMEP_STATUS]]+ecfg.parse_row(self.format, d_info))
            is_idlist=True
        else: #not an idlist
            if self.simple_list: 
                #the model has a simple format, no need to call the pattern parser
                for row_dict in result:
                    row = [ecfg.format_value(val, row_dict[val]) for val in self.list_struct]
                    ids.append(row_dict[ec.XMEP_ID])
                    self.list_model.append(row)
            else:
                for row_dict in result:
                    ids.append(row_dict[ec.XMEP_ID])
                    self.list_model.append( [row_dict[ec.XMEP_ID], ec.XMEP_STATUS]+ecfg.parse_row(self.format, row_dict) )
        
        if not is_idlist and self.enable_sort:
            self.set_headers_clickable(True)
            self.set_model(self.sort_model)
        else:
            self.set_headers_clickable(False)
            self.set_model(self.list_model)
        self.ids = ids
        
        self.emit('collection_loaded', self.coll_name, type(self.collection))

    def __check_medialist(self, coll):
        """check if the given collection is a medialist"""
        cl = ec.Collection(None)
        return cl.check_medialist(coll)

    def __get_loading_row(self):
        ret_list = []
        for type in self.column_types:
            if type == gobject.TYPE_INT:
                ret_list.append(0)
            else:
                ret_list.append(_("Loading"))
        return ret_list

    def collection_changed_cb(self, client, hash):
        """
        Collection changed callback. Modify our structure accordingly
        """

        if (hash[u'name'] != self.coll_name) or (hash[u'namespace'] != self.namespace):
            return False

        if hash[u'type'] == xmmsclient.COLLECTION_CHANGED_REMOVE:
            self.coll_name = ''
            self.list_model.clear()
            del self.ids[0:]
        elif hash[u'type'] == xmmsclient.COLLECTION_CHANGED_RENAME:
            self.coll_name = hash[u'newname']
            self.emit('collection_loaded', self.coll_name, type(self.collection))
        elif hash[u'type'] == xmmsclient.COLLECTION_CHANGED_UPDATE:
            if (hash[u'namespace'] == 'Collections'):
                """
                if the namespace was playlist, we would get e_playlist_changed, so no need """
                self.set_coll_name(self.coll_name, self.namespace)
        return False

    def playlist_changed_cb(self, client, hash):
        """
        Playlist changed callback. Modify our structure
        """

        mlib = self.client.medialib
        if (hash[u'name'] != self.coll_name) or (self.namespace != "Playlists"):
            return False

        if hash[u'type'] in (xmmsclient.PLAYLIST_CHANGED_ADD, xmmsclient.PLAYLIST_CHANGED_INSERT):
            self.ids.insert(hash[u'position'], hash[u'id'])
            row = self.__get_loading_row()
            row[0] = hash[u'id']
            self.list_model.insert(hash[u'position'], row)
            mlib.get_info(hash[u'id'], self.__update_row_minfo)
        elif hash[u'type'] == xmmsclient.PLAYLIST_CHANGED_CLEAR:
            del self.ids[0:]
            self.list_model.clear()
        elif hash[u'type'] == xmmsclient.PLAYLIST_CHANGED_MOVE:
            np = hash[u'newposition']
            pos = hash[u'position']
            del self.ids[pos]
            self.ids.insert(np, hash[u'id'])
            positer = self.list_model.get_iter((pos,))
            npiter = self.list_model.get_iter((np,))
            if np < pos:
                self.list_model.move_before(positer, npiter)
            elif np >pos:
                self.list_model.move_after(positer, npiter)
        elif hash[u'type'] == xmmsclient.PLAYLIST_CHANGED_REMOVE:
            pos = hash[u'position']
            del self.ids[pos]
            self.list_model.remove(self.list_model.get_iter((pos,)))
        elif hash[u'type'] in ( xmmsclient.PLAYLIST_CHANGED_SHUFFLE, xmmsclient.PLAYLIST_CHANGED_SORT):
            self.client.playlist.list_entries(playlist = self.coll_name, cb = self.__changed_reorder)
        elif hash[u'type'] == xmmsclient.PLAYLIST_CHANGED_UPDATE:
            self.set_coll_name(self.coll_name, self.namespace)
        return False

    def __changed_reorder(self, new):
        new_order = [self.ids.index(a) for a in new]
        self.list_model.reorder(new_order)
        self.ids = new

    def playlist_current_pos_cb(self, client, hash):
        """
        callback for recieveng current position in the playlist
        """
        if (hash[u'name'] != self.coll_name) or (self.namespace != "Playlists"):
            return False
        self.playlist_position = int(hash[u'position'])
        self.queue_draw()
        return False

    def __update_row_minfo(self, info):
        id = info.get(u'id')
        index = -1
        while True:
            try:
                index = self.ids.index(id, index+1)
            except ValueError:
                break
            iter = self.list_model.get_iter((index,))
            if self.simple_list:
                #row = [ecfg.format_value(val, info[val]) for val in self.list_struct]
                for i in xrange(1,len(self.list_struct)):
                    val = self.list_struct[i]
                    try:
                        self.list_model.set(iter, i, ecfg.format_value(val, info[val]))
                    except KeyError: #not set in medialib 
                        self.list_model.set(iter, i, None)
            else:
                row = info.get_custom_info(self.format)
                self.list_model.set(iter, 1, int(info[ec.XMEP_STATUS]))
                for i in xrange(len(row)):
                    self.list_model.set(iter, i+2, row[i])
    
    def entry_changed(self, client, id):
        """
        if an entry changed in the collection get information from the server
        and update the row showing the song
        """
        if id not in self.ids:
            return False
        self.client.medialib.get_info(id, self.__update_row_minfo)
        return False

    TARGET_TYPE_URI_LIST = 80
    TARGETS = [ ('ETUDE_PLAYLIST_ROW', gtk.TARGET_SAME_WIDGET, 0), #positions
            ('ETUDE_MEDIALIB_IDS', gtk.TARGET_SAME_APP, 1), #ids
            ('ETUDE_ENCODED_URLS', gtk.TARGET_SAME_APP, 2), #encoded urls
            ('text/uri-list', 0, TARGET_TYPE_URI_LIST)] #urls

    def enable_dnd(self, dest = False, src = False):
        """
        Enable drag and drop support for the collection
        dest - if songs can be inserted into collection
            should not be enabled with standard collections
            id's into a collection cannot be simply inserted
            unless it's an idlist
        src - if songs can be copied from the collection
        """
        if dest :
            targets = self.TARGETS
            profile = self.plugin.control.profile
            if profile.is_remote():
                targets = self.TARGETS[:-1]
            self.enable_model_drag_dest(targets, gtk.gdk.ACTION_DEFAULT | gtk.gdk.ACTION_MOVE)
        else:
            self.unset_rows_drag_dest()
        
        if src :
            self.enable_model_drag_source(gtk.gdk.BUTTON1_MASK,
                    self.TARGETS[:2], #we may not be able to provide the url...
                    gtk.gdk.ACTION_DEFAULT | gtk.gdk.ACTION_COPY)
            
        else:
            self.unset_rows_drag_source()
    
    def on_drag_begin(self, widget, drag_context, data = None):
        """reselect the song under the cursor if it got unselected"""
        path = self.get_path_at_pos(int(self.last_x), int(self.last_y))
        if path == None:
            return False
        sel = self.get_selection()
        if not sel.path_is_selected(path[0]):
            sel.select_path(path[0])
        return False

    def on_after_drag_begin(self, widget, drag_context, data= None):
        """set the icon"""
        icth = gtk.icon_theme_get_default()
        drag_context.set_icon_pixbuf( icth.load_icon('etude', 32, 0), 0, 0)

    def on_drag_data_recieved(self, widget, drag_context, x, y, selection, info, timestamp):
        """
        On drag received - only idlists are supported
        """


        """methods for support of idlists in "Collections" namespace"""
        
        def idl_move(old_pos, new_pos, playlist = None):
            x = self.ids.pop(old_pos)
            self.ids.insert(new_pos, x)

        def idl_insert(pos, ins_id, playlist = None):
            self.ids.insert(pos, ins_id)
        
        def idl_save():
            [self.collection.ids.remove(0) for id in self.collection.ids]
            [self.collection.ids.append(id) for id in self.ids]
            cl = client.Collection(self.client)
            cl.save(self.collection, self.coll_name, self.namespace) 
        
        #model = self.list_model
        model = self.get_model()
        drop_info = self.get_dest_row_at_pos(x, y)
        data = selection.data
        if data == None: 
            if (len(self.coll_name) == 0):
                return
            if (self.namespace == "Playlists"):
                move_func = self.client.playlist.move
            else: #Collections
                move_func = idl_move
            try:
                path, position = drop_info
            except TypeError:
                path = (model.iter_n_children(None)-1,)
                position = None
            new_pos = path[0]
            tsl = self.get_selection()
            model, path_list = tsl.get_selected_rows()
            old_positions = [p[0] for p in path_list]
            old_less = [p for p in old_positions if p<new_pos]
            old_more = [p for p in old_positions if p>=new_pos]
            old_decr = 0
            if (position == gtk.TREE_VIEW_DROP_BEFORE) and old_less:
                new_pos -= 1
            for old_pos in old_less:
                #self.client.playlist.move(old_pos-old_decr, new_pos, playlist = self.coll_name)
                move_func(old_pos-old_decr, new_pos, playlist = self.coll_name)
                if old_pos < new_pos:
                    old_decr += 1
            if position == gtk.TREE_VIEW_DROP_AFTER:
                new_pos +=1
            for old_pos in old_more:
                #self.client.playlist.move(old_pos, new_pos, playlist = self.coll_name)
                move_func(old_pos, new_pos, playlist = self.coll_name)
                new_pos += 1
            if self.namespace == "Collections":
                idl_save()
        elif info == 1: #ids
            if (len(self.coll_name) > 0):
                if self.namespace == "Playlists":
                    insert_func = self.client.playlist.insert_id
                else: #Collections
                    insert_func = idl_insert
                ids = []
                for id in data.strip().split():
                    try:
                        ids.append(int(id))
                    except ValueError:
                        pass
                try:
                    path, position = drop_info
                except TypeError:
                    path = (self.list_model.iter_n_children(None),)
                    position = None
                new_pos = path[0]
                if position in (gtk.TREE_VIEW_DROP_INTO_OR_AFTER, gtk.TREE_VIEW_DROP_AFTER):
                    new_pos += 1
                for id in ids:
                    #self.client.playlist.insert_id(new_pos, id, playlist = self.coll_name)
                    insert_func(new_pos, id, playlist = self.coll_name)
                    new_pos +=1
                if self.namespace == "Collections":
                    idl_save()
        elif info == 2: #encoded urls
            if self.namespace != "Playlists" or self.coll_name == '':
                return
            uris = data.strip('\r\n\00 ')
            encoded_uris = data.split()
            try:
                path, position = drop_info
            except TypeError:
                path = (self.list_model.iter_n_children(None),)
                position = None
            new_pos = path[0]
            if position in (gtk.TREE_VIEW_DROP_INTO_OR_AFTER, gtk.TREE_VIEW_DROP_AFTER):
                new_pos += 1
            for uri in encoded_uris:
                if uri.endswith('/'):
                    self.client.playlist.rinsert_encoded(new_pos, uri, 
                            playlist = self.coll_name)
                else:
                    self.client.playlist.insert_encoded(new_pos, uri,
                            playlist = self.coll_name)
                new_pos +=1           
        elif info == self.TARGET_TYPE_URI_LIST:
            if self.namespace != "Playlists" or self.coll_name == '':
                return
            uris = data.strip('\r\n\00 ')
            encoded_uris = data.split()
            try:
                path, position = drop_info
            except TypeError:
                path = (self.list_model.iter_n_children(None),)
                position = None
            new_pos = path[0]
            if position in (gtk.TREE_VIEW_DROP_INTO_OR_AFTER, gtk.TREE_VIEW_DROP_AFTER):
                new_pos += 1
            for uri in encoded_uris:
                url = urllib.url2pathname(uri)
                path = url
                if path.startswith('file://'):
                    path = path[7:]
                if os.path.isdir(path):
                    self.client.playlist.rinsert(new_pos, url, 
                            playlist = self.coll_name)
                elif os.path.isfile(path):
                    self.client.playlist.insert_url(new_pos, url,
                            playlist = self.coll_name)
                new_pos +=1           


    def on_drag_data_get(self, widget, context, selection, target_id, timestamp):
        viewselection = self.get_selection()
        model, path_list = viewselection.get_selected_rows()
        """
        if target_id == 0: #playlist positions
            data_string = 'pos: '
            for path in path_list:
                data_string += str(path[0])+' '
            print(data_string)
            selection.set_text(data_string, len(data_string))
        """
        if target_id == 0:
            if not self.namespace == "Playlists":
                return
        elif target_id == 1: #ids
            data_string = ''
            for path in path_list:
                iter = model.get_iter(path) 
                data_string += str(model.get_value(iter, 0))+ ' '
            str(selection.set(selection.target, 8, data_string))

gobject.type_register(CollectionView)
gobject.signal_new("collection_loaded", CollectionView, gobject.SIGNAL_RUN_LAST, gobject.TYPE_BOOLEAN, (gobject.TYPE_STRING, gobject.TYPE_PYOBJECT)) 
#notifies when the collection was loaded -> cb(cview, collection_name, collection_class)

